import {
	defineStore
} from 'pinia';
import request from '@/utils/request.js'
import {
	chatApi
} from '@/apis/cloud/chat'
import {
	compareVersions
} from '@/utils/tools.js'
import {
	COMMON_API_BASE_URL
} from '@/utils/request.js'
import {
	debounce
} from "@/utils/index.js"
export const useLoginStore = defineStore({
	id: 'login', // id必填，且需要唯一
	state: () => {
		return {
			token: uni.getStorageSync('token') || null,
		}
	},
	// actions 用来修改 state
	actions: {
		login(token) {
			// 后期添加本地DB
			this.token = token
			uni.setStorageSync('token', token)
		},
		logout() {
			this.token = null
			uni.removeStorageSync('token')
		}
	}
})

export const useUserStore = defineStore({
	id: 'user', // id必填，且需要唯一
	state: () => {
		return {
			user: uni.getStorageSync('user') ? JSON.parse(uni.getStorageSync('user')) : null,
			roles: null,
		}
	},
	// actions 用来修改 state
	actions: {
		setUser(user) {
			// 后期添加本地DB
			this.user = user
			uni.setStorageSync('user', JSON.stringify(user))
		},
		setRoles(roles) {
			this.roles = roles
		}
	},
	// 仅在 H5 启用持久化
	persist: process.env.VUE_APP_PLATFORM === 'h5' ? {
		enabled: true,
		strategies: [{
			key: 'user',
			storage: localStorage, // H5 专用
		}, ],
	} : false
})

export const useClockStore = defineStore({
	id: 'clock', // id必填，且需要唯一
	state: () => {
		return {
			clock: null,
		}
	},
	// actions 用来修改 state
	actions: {
		setClock(data) {
			// 后期添加本地DB
			this.clock = data
		},
	}
})

// 搜索存储人员
export const useSearchStore = defineStore({
	id: 'search',
	state: () => {
		return {
			person: null,
			groups: null
		}
	},
	// actions 用来修改 state
	actions: {
		setPerson(data) {
			this.person = data
		},
		setGroups(data) {
			this.groups = data
		},
	},
	// 仅在 H5 启用持久化
	persist: process.env.VUE_APP_PLATFORM === 'h5' ? {
		enabled: true,
		strategies: [{
			key: 'search',
			storage: localStorage,
		}, ],
	} : false
})

// 单聊
export const useChatStore = defineStore({
	id: 'chat', // id必填，且需要唯一
	state: () => {
		return {
			chat: null,
			imInfo: null
		}
	},
	// actions 用来修改 state
	actions: {
		setChat(data) {
			// 后期添加本地DB
			this.chat = data
		},
		setImInfo(data) {
			// 后期添加本地DB
			this.imInfo = data
		},
	},
	// 仅在 H5 启用持久化
	persist: process.env.VUE_APP_PLATFORM === 'h5' ? {
		enabled: true,
		strategies: [{
			key: 'chat',
			storage: localStorage, // H5 专用
		}, ],
	} : false
})

// 群聊
export const useGroupStore = defineStore({
	id: 'group', // id必填，且需要唯一
	state: () => {
		return {
			group: null,
		}
	},
	// actions 用来修改 state
	actions: {
		setGroup(data) {
			// 后期添加本地DB
			this.group = data
		},
	},
	// 仅在 H5 启用持久化
	persist: process.env.VUE_APP_PLATFORM === 'h5' ? {
		enabled: true,
		strategies: [{
			key: 'group',
			storage: localStorage, // H5 专用
		}, ],
	} : false
})

// 剪切
export const useCopyStore = defineStore({
	id: 'copy', // id必填，且需要唯一
	state: () => {
		return {
			copyValue: null,
		}
	},
	// actions 用来修改 state
	actions: {
		setCopyValue(data) {
			// 后期添加本地DB
			this.copyValue = data
		},
	}
})

export const useSocketStore = defineStore({
	id: 'socket',
	state: () => {
		return {
			socket: null, // WebSocket 实例
			isConnected: false, // 重连
			reConnected: null,
			heart: null, // 心跳
			lastMsg: null,
			nowDialogId: null,
			url: null,
			cache: null,
			isReconnect: false,
			userStore: null,
			chatStore: null,
			client: null,
			isManualClose: false, // 是否手动关闭 退出登录
			badgeNum: null
		}
	},
	actions: {
		async getChatList() {
			if (!this.userStore && !this.chatStore) {
				this.userStore = useUserStore()
				this.chatStore = useChatStore()
			}

			const params = {
				'data[account]': this.userStore.user.chat_account,
				'data[token]': this.userStore.user.token,
				'data[uid]': this.chatStore.imInfo.id,
				// url: 'index.php/users/Index/getMyChatRecord'
				// url: 'index.php/users/Index/getMyTree'
				url: 'index.php/users/Index/getChatListCached'
			}

			const msg = await chatApi(this.userStore.user.token, params);
			let num = 0;
			msg.data.friends.forEach(item => {
				num += item.unread_num;
			})
			this.badgeNum = num;
			uni.$emit('update', msg.data.friends)
			if (num > 99) {
				uni.setTabBarBadge({
					index: 0,
					text: `99`
				})
			} else if (num > 0) {
				uni.setTabBarBadge({
					index: 0,
					text: `${num}`
				})
			} else {
				uni.removeTabBarBadge({
					index: 0
				})
			}
		},
		debouncedFetch: debounce(function() {
			this.getChatList();
		}, 500),
		/**
		 * 初始化连接
		 * @param {Object} data
		 */
		init(data) {
			const _self = this;
			if (this.isConnected) return; // 避免重复连接
			this.isManualClose = false; // 每次登录时候进行重置
			this.cache = data; // 重连使用

			// if (uni.getSystemInfoSync().platform == 'ios' || uni.getSystemInfoSync().osName == 'ios') {
				this.url = "wss://chat.mfarmers.com:88/ws/?from_type=pc&account=" + data.account + "&groupStr=" + data.groupStr;
			// } else {
			// 	this.url = "wss://chat.mfarmers.com:89/?from_type=pc&account=" + data.account + "&groupStr=" + data.groupStr;
			// }
			console.log('WebSocket init');
			// H5打开websocket通道
			// #ifdef H5
			this.socket = new WebSocket(this.url);
			// H5通道打开后发送连接心跳信息
			clearInterval(this.heart);
			this.heart = null;
			this.heartbeat();
			// 发送登录用户信息
			try {
				const sendData = {
					type: "init",
					data: {
						account: data.account,
						groupStr: data.groupStr
					}
				};
				this.socket.onopen = () => {
					this.isConnected = true;
					this.send(sendData);
				}
			} catch (err) {
				console.log('connected failed', err);
				_self.reconnect();
			}
			// #endif

			// APP打开websocket通道
			// #ifdef APP-PLUS
			this.socket = uni.connectSocket({
				url: this.url,
				success(event) {
					console.log('success', event)
				}
			});

			// APP绑定事件处理器
			this.socket.onOpen((evnet) => {
				this.isConnected = true;
				// 发送登录用户信息
				const sendData = {
					type: "init",
					data: {
						account: data.account,
						groupStr: data.groupStr
					}
				}
				this.send(sendData);
				clearInterval(this.heart);
				this.heart = null;
				this.heartbeat();
			})
			// #endif


			// #ifdef APP-PLUS
			this.socket.onMessage((msg) => {
				const {
					data
				} = msg;
				const res = JSON.parse(data);

				if (res.type == 'chatMessage') {
					this.lastMsg = res;
					this.notifyUser()
				}

				if (res.type == 'haveRead') {
					uni.$emit('setHaveRead', res);
				}

				if (res.type == 'groupHaveRead') {
					uni.$emit('setGroupHaveRead', res);
				}

				if (res.raw_type == 'update-received-list') {
					uni.$emit('updaterReceived', res.data);
				}

				if (res.raw_type == "update-relations") {
					uni.$emit('updateRelations', res.data);
				}

				if (res.raw_type == 'update-msg-follower') {
					uni.$emit(`update-msg-follower`, res.data)
				}

				if (res.raw_type == 'recall-message' && res.chatType == 'friend') {
					uni.$emit('setRecallMessage', res);
				}

				if (res.raw_type == 'recall-message' && res.chatType == 'group') {
					uni.$emit('setGroupRecallMessage', res);
				}

				if (res.type == 'connected') {
					this.client = res.client_id;
				}

				if (res.type == 'haveRead' && res.type == 'groupHaveRead' && res.type ==
					'recall-message' && res.type == 'chatMessage') {
					this.debouncedFetch();
				}
			})
			// #endif

			// #ifdef H5
			this.socket.onmessage = (msg) => {
				const {
					data
				} = msg;
				const res = JSON.parse(data);

				if (res.type == 'chatMessage') {
					this.lastMsg = res;
					this.notifyUser()
				}

				if (res.type == 'haveRead') {
					uni.$emit('setHaveRead', res);
				}

				if (res.type == 'groupHaveRead') {
					uni.$emit('setGroupHaveRead', res);
				}

				if (res.raw_type == 'update-received-list') {
					uni.$emit('updaterReceived', res.data);
				}

				if (res.raw_type == "update-relations") {
					setTimeout(() => {
						uni.$emit('updateRelations', res.data);
					}, 200)
				}

				if (res.raw_type == 'update-msg-follower') {
					uni.$emit(`update-msg-follower`, res.data)
				}

				if (res.raw_type == 'recall-message' && res.chatType == 'friend') {
					uni.$emit('setRecallMessage', res);
				}

				if (res.raw_type == 'recall-message' && res.chatType == 'group') {
					uni.$emit('setGroupRecallMessage', res);
				}

				if (res.type == 'connected') {
					this.client = res.client_id;
				}

				if (res.type == 'haveRead' && res.type == 'groupHaveRead' && res.type == 'recall-message' &&
					res.type == 'chatMessage') {
					this.debouncedFetch();
				}
			}
			// #endif

			// #ifdef APP-PLUS
			this.socket.onClose(() => {
				// if(_self.isReconnect) return;
				if (_self.isManualClose) { // 如果是手动关闭，不重连
					console.log('WebSocket 已手动关闭，不重连');
					return;
				}
				console.log('服务断开 正在重连...app');
				_self.isConnected = false;
				_self.reconnect(); // 自动重连
			})
			// #endif

			// #ifdef H5
			this.socket.onclose = () => {
				// if(_self.isReconnect) return;
				if (_self.isManualClose) { // 如果是手动关闭，不重连
					console.log('WebSocket 已手动关闭，不重连');
					return;
				}
				console.log('服务断开 正在重连...h5')
				_self.isConnected = false;
				_self.reconnect(); // 自动重连
			}
			// #endif
		},

		// 发送消息
		send(data) {
			const _self = this;
			const msg = JSON.stringify(data);
			// #ifdef APP-PLUS
			if (this.isConnected && this.socket) {
				this.socket.send({
					data: msg,
					async success() {},
					fail(err) {
						console.error("【APP】消息发送失败:", err);
						_self.isConnected = false;
						_self.socket = null;
						_self.reconnect();
					},
				});
			} else {
				console.warn("【APP】WebSocket 未连接，消息未发出:", msg);
			}
			// #endif

			// #ifdef H5
			if (this.isConnected && this.socket) {
				try {
					if (this.socket.readyState === WebSocket.OPEN) {
						this.socket.send(msg);
					} else {
						console.warn("【H5】WebSocket 未打开，消息未发出:", msg);
					}
				} catch (err) {
					console.error("【H5】消息发送失败:", err);
					_self.isConnected = false;
					_self.socket = null;
					_self.reconnect();
					this.cacheMessage(data);
				}
			} else {
				console.warn("【H5】WebSocket 未连接，消息未发出:", msg);
			}
			// #endif
		},
		// 心跳
		heartbeat() {
			this.heart = setInterval(() => {
				this.send({
					type: "onLine",
					data: {
						jump: 1
					}
				});
			}, 30000)
		},
		// 主动断连
		handleClose() {
			this.isManualClose = true; // 标记为手动关闭
			clearInterval(this.heart);
			this.heart = null;

			// #ifdef H5
			if (this.socket) this.socket.close();
			// #endif

			// #ifdef APP-PLUS
			if (this.socket) {
				this.socket.close({
					code: 1000,
					success() {
						console.log('连接主动关闭');
					},
					fail(err) {
						console.log('主动关闭失败', err);
					}
				});
			}
			// #endif

			this.socket = null;
			this.isConnected = false;
			clearInterval(this.reConnected);
			this.reConnected = null;
			this.isReconnect = false;
			this.cache = null;
		},
		// 自动重连逻辑
		reconnect(url) {
			// 用户主动关闭，不重连
			if (this.isManualClose) {
				console.log("已手动关闭，不执行重连");
				return;
			}

			// 如果已经在重连中，直接返回
			if (this.isReconnect) return;

			this.isReconnect = true;
			this.isConnected = false;

			// 如果已有定时器，先清理
			if (this.reConnected) {
				clearInterval(this.reConnected);
				this.reConnected = null;
			}

			// 启动定时器，每隔 5 秒尝试重连
			this.reConnected = setInterval(() => {
				if (this.isConnected) {
					// 已经连接成功，停止重连
					clearInterval(this.reConnected);
					this.reConnected = null;
					this.isReconnect = false;
					uni.$emit('reConnected');
					return;
				}

				// #ifdef H5
				try {
					this.socket.onopen = null;
					this.socket.onclose = null;
					this.socket.onmessage = null;
					this.socket.onerror = null;
					this.socket.close();
					console.log("【H5】旧连接已关闭");
					console.log("【H5】:", new Date());
				} catch (e) {
					console.error("【H5】关闭旧连接异常:", e);
				}
				// #endif

				// #ifdef APP-PLUS
				try {
					this.socket.close({
						code: 1000,
						reason: "reconnect"
					});
					console.log("【APP】旧连接已关闭");
					console.log("【APP】:", new Date());
				} catch (e) {
					console.error("【APP】关闭旧连接异常:", e);
				}
				// #endif

				// 尝试使用缓存连接
				if (this.cache && this.cache.account) {
					this.init(this.cache);
				} else {
					uni.getStorage({
						key: '_ws',
						success: (res) => {
							this.init(JSON.parse(res.data));
						}
					});
				}
			}, 5000);
		},

		setunlockedAudio(value) {
			this.unlockedAudio = value
		},
		notifyUser() {
			console.log('触发通知播放事件');
			uni.$emit('playNotifyAudio');
		}
	}
});

export const useStartTodoPolling = defineStore({
	id: 'todoPolling',
	state: () => ({
		timer: null, // 定时器
		checkTokenTimer: null, // 检测token定时器
		total: 0, // 待办数量
		errorCount: 0, // 待办错误次数
		currentInterval: 6000, // 当前轮询间隔
	}),
	actions: {
		start(tabIndex = 2, baseInterval = 6000, maxErrors = 2, errorInterval = 45000) {
			if (this.timer || this.checkTokenTimer) return;

			this.currentInterval = baseInterval;
			this.checkTokenTimer = setInterval(() => {
				const token = uni.getStorageSync('token');
				if (token) {
					clearInterval(this.checkTokenTimer);
					this.checkTokenTimer = null;

					if (this.timer) clearTimeout(this.timer);

					const fetch = () => {
						const query = {
							pageSize: 10,
							row: 10,
							page: 1,
							keywords: '',
							type: 0,
							time: 1,
							style: 1,
						};

						request({
								url: '/index/BackLog/daiban_index',
								method: 'POST',
								data: query,
							})
							.then((res) => {
								if (res.status > 0) {
									this.errorCount = 0;
									this.currentInterval = baseInterval;

									this.total = res.data.daiban_num > 99 ? "99+" : res.data
										.daiban_num;
								} else {
									uni.$u.toast(res.data.msg || '待办加载失败，请稍后再试或重新登录');
									this.errorCount++;
									this.currentInterval = errorInterval;

									if (this.errorCount >= maxErrors) {
										console.warn(`接口连续失败${maxErrors}次，已停止轮询`);
										this.stop();
										return;
									}

									this.total = 0;
								}
							})
							.catch((err) => {
								uni.$u.toast(err.data.msg || '待办加载失败，请稍后再试或重新登录');
								this.errorCount++;
								this.currentInterval = errorInterval;

								if (this.errorCount >= maxErrors) {
									console.warn(`接口连续失败${maxErrors}次（异常），已停止轮询`);
									this.stop();
									return;
								}

								this.total = 0;
							})
							.finally(() => {
								this.timer = setTimeout(fetch, this.currentInterval);
							});
					};

					fetch(); // 启动首次请求
				}
			}, 1000);
		},

		stop() {
			if (this.timer) {
				clearTimeout(this.timer);
				this.timer = null;
			}
			if (this.checkTokenTimer) {
				clearInterval(this.checkTokenTimer);
				this.checkTokenTimer = null;
			}
			this.errorCount = 0;
			this.total = 0;
			this.currentInterval = 6000;
		},

		restart() {
			this.stop();
			this.start();
		}
	}
});

// 检测版本更新
export const useVersionStore = defineStore({
	id: 'version',
	state: () => ({
		newVision: 0, // 新版本号
		upLoadUrl: '', // 下载地址
		appStoreUrl: '', // 下载地址
		log: '', // 更新日志
		hasUpdate: false, // 是否有更新
		version: null
	}),
	actions: {
		async checkVersion() {
			try {
				const info = uni.getSystemInfoSync()
				const res = await new Promise((resolve, reject) => {
					uni.request({
						url: `${COMMON_API_BASE_URL}/dist/interface/public/index.php/index/Index/get_new_version`,
						method: 'POST',
						success: resolve,
						fail: reject,
						timeout: 8000
					})
				})

				if (res?.data?.data?.code === 0) return


				// #ifdef H5
				this.version = info?.appVersion || uni.getStorageSync('localVersion')
				// #endif

				// #ifdef APP-PLUS
				this.version = info.appWgtVersion
				// #endif

				if (compareVersions(this.version, res?.data?.data?.version_no) === -1) {
					this.newVision = res?.data?.data?.version_no
					this.upLoadUrl = "https://cloud.mfarmers.com" + res?.data?.data?.url
					this.log = res?.data?.data?.remark
					this.hasUpdate = true
					setTimeout(async () => {
						uni.setTabBarBadge({
							index: '4',
							text: '新',
						});
					}, 1000);

				} else {
					this.hasUpdate = false
					uni.removeTabBarBadge({
						index: '4',
					});
				}
			} catch (err) {
				console.error('检测版本失败', err)
				// uni.showToast({ title: '网络异常', icon: 'none' })
				// uni.reLaunch({
				// 	url: "/pages/user/login"
				// });
			}
		},

		// 停止定时器
		reset() {
			this.newVision = 0
			this.upLoadUrl = ''
			this.appStoreUrl = ''
			this.log = ''
			this.hasUpdate = false
			uni.removeTabBarBadge({
				index: '4'
			})
		},
		// h5 更新 hasUpdate
		sethasUpdate(version, value) {
			const systemInfo = uni.getSystemInfoSync();
			this.hasUpdate = value
			this.version = systemInfo.appVersion
			// #ifdef H5
			uni.setStorageSync('localVersion', systemInfo.appVersion);
			this.checkVersion()
			uni.removeTabBarBadge({
				index: 4
			})
			setTimeout(() => {
				location.reload()
			}, 0)
			// #endif
		}
	}
})


// 存储群聊头像
export const useChatsettings = defineStore({
	id: 'Chatsettings',
	state: () => ({
		selection: []
	}),
	actions: {
		setselection(value) {
			this.selection = value
		},
	}
});